package game.games.gol;



public class GameOfLifeRule
{
    public static final GameOfLifeRule DEFAULT = new GameOfLifeRule("23/3");
    public static final GameOfLifeRule X000001 = new GameOfLifeRule("3/3");
    public static final GameOfLifeRule X000002 = new GameOfLifeRule("13/3");
    public static final GameOfLifeRule X000003 = new GameOfLifeRule("34/3");
    public static final GameOfLifeRule X000004 = new GameOfLifeRule("35/3");
    public static final GameOfLifeRule X000005 = new GameOfLifeRule("2/3");
    public static final GameOfLifeRule X000006 = new GameOfLifeRule("24/3");
    public static final GameOfLifeRule X000007 = new GameOfLifeRule("245/3");
    public static final GameOfLifeRule X000008 = new GameOfLifeRule("125/36");
    public static final GameOfLifeRule X000009 = new GameOfLifeRule("236/3");
    public static final GameOfLifeRule X000010 = new GameOfLifeRule("135/35");
    public static final GameOfLifeRule X000011 = new GameOfLifeRule("12345/3");
    public static final GameOfLifeRule X000012 = new GameOfLifeRule("1357/1357");
    public static final GameOfLifeRule X000013 = new GameOfLifeRule("0123/01234");
    
    public static GameOfLifeRule[] getRules()
    {
        return new GameOfLifeRule[] { DEFAULT, X000001, X000002, X000003, X000004, X000005, X000006, X000007, X000008, X000009, X000010, X000011, X000012, X000013 };
    }
    // attribute
    private boolean[]                   survive = new boolean[] { false, false, false, false, false, false, false, false, false };
    private boolean[]                   birth   = new boolean[] { false, false, false, false, false, false, false, false, false };

    public GameOfLifeRule(String rule)
    {
        int trenner = rule.indexOf("/");
        if (trenner <= 0)
        {
            throw new IllegalArgumentException("illegal rule: " + rule);
        }
        String ruleSurvive = rule.substring(0, trenner);
        for (int i = 0; i < ruleSurvive.length(); i++)
        {
            int index = Integer.parseInt(ruleSurvive.substring(i, i + 1));
            survive[index] = true;
        }
        String ruleBirts = rule.substring(trenner + 1);
        for (int i = 0; i < ruleBirts.length(); i++)
        {
            int index = Integer.parseInt(ruleBirts.substring(i, i + 1));
            birth[index] = true;
        }
    }
    
    public String getRule()
    {
        StringBuilder rule = new StringBuilder();
        for (int i = 0; i < survive.length; i++)
        {
            if (survive[i])
            {
                rule.append(i);
            }
        }
        rule.append("/");
        for (int i = 0; i < birth.length; i++)
        {
            if (birth[i])
            {
                rule.append(i);
            }
        }
        return rule.toString();
    }
    
    public void invert()
    {
        for (int i = 0; i < survive.length; i++)
        {
            survive[i] = (survive[i] == false);
        }
        for (int i = 0; i < birth.length; i++)
        {
            birth[i] = (birth[i] == false);
        }
    }
    
    private void checkNeighborCount(int neighbors)
    {
        if (neighbors < 0 || neighbors > 8)
        {
            throw new IllegalArgumentException("neighbors != 8 : " + neighbors);
        }
    }
    
    public boolean isSurviving(boolean isAlive, int neighbors)
    {
        checkNeighborCount(neighbors);
        boolean result = isAlive;
        if (isAlive)
        {
            result = survive[neighbors];
        }
        else
        {
            result = birth[neighbors];
        }
        return result;
    }
    
    public boolean isSurviving(int neighbors)
    {
        checkNeighborCount(neighbors);
        boolean result = false;
        result = survive[neighbors];
        return result;
    }
    
    public boolean isDieing(int neighbors)
    {
        checkNeighborCount(neighbors);
        boolean result = false;
        result = birth[neighbors];
        return result;
    }
}
